package com.ndood.reconciliation.domain.recon.service;

import java.util.Date;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ndood.api.app.tools.IdUtils;
import com.ndood.common.base.constaints.CommonConstaints;
import com.ndood.common.base.util.DateUtil;
import com.ndood.reconciliation.base.dao.recon.ExtendReconBatchDao;
import com.ndood.reconciliation.base.dao.recon.ExtendReconScratchDao;
import com.ndood.reconciliation.domain.recon.entity.dto.ReconBatchDto;
import com.ndood.reconciliation.domain.recon.entity.dto.ReconMistakeDto;
import com.ndood.reconciliation.domain.recon.entity.dto.ReconScratchDto;
import com.ndood.reconciliation.domain.recon.repository.ReconBatchRepository;
import com.ndood.reconciliation.domain.recon.repository.ReconMistakeRepository;
import com.ndood.reconciliation.domain.recon.repository.ReconScratchRepository;

import lombok.extern.slf4j.Slf4j;

/**
 * 对账公共服务
 */
@Service
@Slf4j
public class ReconCommonService {
	
	@Autowired
	private ExtendReconBatchDao extendReconBatchDao;
	
	@Autowired
	private ReconBatchRepository reconBatchRepository;
	
	@Autowired
	private IdUtils idUtils;
	
	@Autowired
	private ExtendReconScratchDao reconScratchDao;
	
	@Autowired
	private ReconScratchRepository reconScratchRepository;
	
	@Autowired
	private ReconMistakeRepository reconMistakeRepository;
	
	/**
	 * 1 查询出对账批次信息
	 */
	public ReconBatchDto getReconBatch(String date, Integer payWay) {
		ReconBatchDto batch = extendReconBatchDao.extendFindReconBatchByDateAndPayWay(date, payWay);
		return batch;
	}

	/**
	 * 2 创建一个新批次
	 */
	public void initReconBatch(String date, Integer payWay) {
		ReconBatchDto batch = new ReconBatchDto();
		batch.setBatchNo(idUtils.getNextId());
		batch.setPayWay(payWay);
		batch.setReconDay(date);
		batch.setReconType(CommonConstaints.RECON_TYPE_OFFLINE);
		batch.setStatus(CommonConstaints.RECON_BATCH_STATUS_CREATED);
		reconBatchRepository.insertReconBatch(batch);
	}

	/**
	 * 更新对账结果数据 TODO 待重构成批处理形式
	 */
	@Transactional
	public void refreshReconBatchData(ReconBatchDto batch, List<ReconMistakeDto> mistakeList,
			List<ReconScratchDto> insertScratchList, List<ReconScratchDto> removeScratchList) {
		// Step1: 保存差错记录
		reconMistakeRepository.batchAddMistakes(mistakeList);
		
		// Step2: 保存缓存记录
		reconScratchRepository.batchAddScratchs(insertScratchList);
		
		// Step3: 删除缓存记录
		reconScratchRepository.batchDeleteScratchs(removeScratchList);
		
		// Step4: 更新对账批次状态
		ReconBatchDto temp = new ReconBatchDto();
		temp.setId(batch.getId());
		temp.setStatus(CommonConstaints.RECON_BATCH_STATUS_RECONED);
		reconBatchRepository.updateReconBatchById(temp);
	}
	
	/**
	 * 7 将缓冲池里的超时订单存放到错误队列
	 */
	public void processOvertimeMistakes() {
		// Step1: 查询出缓冲池超过3天的数据
		Date now = DateUtil.getCurrentDay();
		Date before3Days = DateUtil.getBeforeDate(now, 3, 0, 0, 0);
		List<ReconScratchDto> scratchList = reconScratchDao.extendFindScratchListBeforeDate(before3Days);
		
		// Step2: 将数据存入错误队列
		if(scratchList.isEmpty()) {
			log.info("缓冲队列中没有数据！");
			return;
		}
		// 待冲构成批量插入
		scratchList.forEach(temp -> {
			ReconMistakeDto dto = new ReconMistakeDto();
			try {
				BeanUtils.copyProperties(dto, temp);
			} catch (Exception e) {
				log.error(e.getMessage(), e);
			}
			dto.setId(null);
			reconMistakeRepository.addMistake(dto);
		});
		
		// Step3: 清理掉超时记录
		reconScratchRepository.deleteScratchBeforeDate(before3Days);
	}

}
